eval 'exec perl -wS $0 ${1+"$@"}'
 if 0;

use strict;
use warnings;
use POSIX qw(strftime);
use Mail::Sendmail;

# Following variable is used as a general file descriptor for all the 
# output of the current tool (the log file). Actually, this file will
# contain the copy of both the stdout and stderr channel.
my $G_LOG;

################################################################################
# NAME: get_base_name
#
# PURPOSE: returns the basename of a file (prefixed path is removed).
#
# INPUT:
#     - filename: string: the file name from which to remove the path.
#     - file extension: string. this argument is optional. If given (like '.dat')
#       then the returned value will have this extension removed.
#
# OUTPUT: None.
#
# RETURN VALUE: string: base name of the input file. If the extension argument is
#               also given, then the extension is also removed from the returned
#               value.
#
# NOTE: This function should work for both Windows and Linux operating system.
#
################################################################################
sub get_base_name
  {
    my ($filename, $file_extension)=shift @_;
    my $basename ="";

    # Note that the following regexp should work for both Unix and
    # Windows path names.
    if ( $filename!~m@^(?:.+[\\/])?([^\\/]+)$@ )
      {
	error("get_base_name failed to match regexp.\n");
	exit(1);
      }

    $basename=$1;

    if (defined $file_extension)
      {
	$basename=~s@$file_extension$@@;
      }

    return($basename);
}

################################################################################
# NAME: get_dir_name
#
# PURPOSE: returns the path of a given file name.
#
# INPUT:
#     - filename: string: the file name from which to retrieve the path.
#
# OUTPUT: None.
#
# RETURN VALUE: string: dir name of the input file.
#
# NOTE: This function should work for both Windows and Linux operating system.
#
################################################################################
sub get_dir_name
  {
    my $filename=shift @_;
    my $dirname ="";

 #   print  "get_dir_name: >$filename<\n";

    # Note that the following regexp should work for both Unix and
    # Windows path names.
#    if ( ! $filename=~m@^(.+)[\\\/][^\\\/]+$@ )
    if ( $filename!~m@^(.+)[\\/][^\\/]+$@ )
      {
	error("get_dir_name failed to match regexp.\n");
	exit(1);
      }

    $dirname=$1;
#    print "get_dir_name: >$dirname<\n";
#    exit 1;

    return($dirname);
}
################################################################################
#
################################################################################
sub get_time
  {
    my $separator=shift @_;
    my $now_time="";

    if (! defined $separator)
      {
	$separator=":";
      }

    $now_time = strftime("%H".$separator."%M".$separator."%S",localtime());

    return $now_time;
  }

################################################################################
#
################################################################################
sub get_date
  {
    my $separator=shift @_;
    my $now_date="";

    if (! defined $separator)
      {
	$separator="/";
      }

    $now_date = strftime("%Y".$separator."%m".$separator."%d",localtime());

    return $now_date;
  }

################################################################################
#
################################################################################
sub mylog
{
    if ($G_LOG)
    {
	print $G_LOG get_date()." ".get_time()." ".join("",@_);
    }
}

################################################################################
#
################################################################################
sub error
  {
    print STDERR get_date()." ".get_time()." [ERROR] ",@_;
    mylog "[ERROR] ", @_;
  }

################################################################################
#
################################################################################
sub warning
  {
    print STDERR get_date()." ".get_time()." [WARNING] ",@_;
    mylog("[WARNING],",@_);
  }

################################################################################
#
################################################################################
sub debug
  {
    my $h_ref_param=shift @_;

    if (exists $h_ref_param->{DEBUG})
      {
	print STDOUT get_date()." ".get_time()." [DEBUG] ",@_;
	mylog("[DEBUG] ",@_);
      }
  }

################################################################################
#
################################################################################
sub info
{
    print STDOUT get_date()." ".get_time()." [INFO] ",@_;
    mylog("[INFO] ",@_);
}


################################################################################
#
################################################################################
sub process
{
    my $h_ref_param=shift @_;
    my %mail=();
    my $server = "172.24.61.99";
    my $line="";
    my $res;

    $mail{Smtp} = $server;
    $mail{Subject} = $h_ref_param->{SUBJECT};
    $mail{From} = $h_ref_param->{FROM};
    $mail{To}   = $h_ref_param->{RECIPIENT};

    $mail{Message}="";
    while ($line=readline($h_ref_param->{BODY}))
    {
	$mail{Message} .= $line;
    }

    $res=sendmail %mail;

   return $res; # True if ok else false if failure.
}

################################################################################
#
################################################################################
sub print_version
{
  my $h_ref_param=shift @_;
  print $h_ref_param->{EXECUTABLE_NAME}." ".$h_ref_param->{VERSION}." ".$h_ref_param->{RELEASE_DATE}."\n";
}

################################################################################
#
################################################################################
sub parse_args
{
    my $h_ref_param=shift @_;

    my $arg="";
    my $err=0;

    while ($arg=shift @ARGV)
      {
	  chomp($arg);
        if ( $arg =~ /^-/ )
          {
            if ( ($arg =~ /^-h/) || ($arg =~ /^--help/))
              {
                print_usage($h_ref_param);
                exit(0);
              }
            elsif ( ($arg =~ /^-d/) || ($arg =~ /^--debug/))
              {
                $h_ref_param->{DEBUG}=1;
              }
            elsif ( ($arg =~ /^-v/) || ($arg =~ /^--version/))
              {
                print_version();
		exit(0);
              }
            elsif ( ($arg =~ /^-f/) || ($arg =~ /^--from/))
              {
		  my $oldarg=$arg;
		  $arg=shift @ARGV;
		  if (!defined $arg)
		  {
		      error "Expected sender parameter after $oldarg switch.\n";
		      $err++;
		      next;
		  }
		  chomp($arg);
		  $h_ref_param->{FROM}=$arg;
              }
            elsif ( ($arg =~ /^-t/) || ($arg =~ /^--to/))
              {
		  my $oldarg=$arg;
		  $arg=shift @ARGV;
		  if (!defined $arg)
		  {
		      error "Expected coma separated recipients list parameter after $oldarg switch.\n";
		      $err++;
		      next;
		  }
		  chomp($arg);
		  $h_ref_param->{RECIPIENT}=$arg;
              }
            elsif ( ($arg =~ /^-s/) || ($arg =~ /^--subject/))
              {
		  my $oldarg=$arg;
		  $arg=shift @ARGV;
		  if (!defined $arg)
		  {
		      error "Expected subject parameter after $oldarg switch.\n";
		      $err++;
		      next;
		  }
		  chomp($arg);
		  $h_ref_param->{SUBJECT}=$arg;
              }
	    else
	      {
		  
                error "Unexpected option >$arg<.\n";
                $err++;
                next;
	      }
          } # if ( $arg =~ /^-/ )
	  else
	  {
	      if (! exists $h_ref_param->{BODYFILE})
	      {
		  $h_ref_param->{BODYFILE}=$arg;
		  if (! -f $arg)
		  {
		      error "File >$arg< doesn't exists or cannot be reached.\n";
		      $err++;
		      next;
		  }

		  open($h_ref_param->{BODY},"<$arg") || die "Failed to open >$arg<.";
	      }

	  } # # if ( $arg =~ /^-/ )

      } # while ($arg=shift @ARGV)

    if (! exists $h_ref_param->{FROM})
    {
	error "Send argument missing.\n";
	$err++;	
    }

    if (! exists $h_ref_param->{RECIPIENT})
    {
	error "Recipients list argument missing.\n";
	$err++;	
    }

    if (! exists $h_ref_param->{SUBJECT})
    {
	error "Subject argument missing.\n";
	$err++;	
    }

    if (! exists $h_ref_param->{BODY})
    {
	$h_ref_param->{BODY}=*STDIN;
    }

    return $err;
}

################################################################################
#
################################################################################
sub print_usage
  {
    my $h_ref_param=shift @_;

    print "USAGE: ".$h_ref_param->{EXECUTABLE_NAME}." [-h|--help] [-d|--debug] [-v|--version]...] -f|--from <sender> -t|--to <recipient list> -s|--subject <subject> [ <file> ]\n";
    print "\n";
    print "PURPOSE:\n";
    print "   Send email to the specified recipient with specified subject and body.\n";
    print "\n";
    print "PARAMETERS DESCRIPTION:\n";
    print "   -f|--from <sender>: Mandatory. Sender email address.\n";
    print "   -t|--to <recipient list>: Mandatory. Coma separated list of recipients.\n";
    print "   -s|--subject <subject>: Mandatory. Subject of the email.\n";
    print "   [ <file> ]: Optional. File containing the body of the message. If not.\n";
    print "               given, then body is taken from STDIN.\n";
    print "\n";
    print "OPTIONS DESCRIPTION:\n";
    print "   [-h|--help]:\n";
    print "      Print this usage message and exit.\n";
    print "\n";
    print "   [-v|--version]:\n";
    print "      Print the version number and exit.\n";
    print "\n";
    print "   [-d|--debug]:\n";
    print "      Print excessive output to understand the processing.\n";
    print "\n";
    print "\n";
  }

################################################################################
#
################################################################################
sub intro
  {
    my $h_ref_param=shift @_;

    # Updating some global variables.
    $h_ref_param->{START_TIME}=get_date()." ".get_time();
    $h_ref_param->{VERSION}="0.1.0";
    $h_ref_param->{EXECUTABLE_NAME}="sendmail.pl";

    # Creating log file
    $h_ref_param->{LOG}=get_base_name($h_ref_param->{EXECUTABLE_NAME}).".log";
    if (! open($G_LOG,">".$h_ref_param->{LOG}))
    {
	warning "Cannot create log file ".$h_ref_param->{LOG}." in current directory.\n";

	$h_ref_param->{LOG}="/tmp/".get_base_name($h_ref_param->{EXECUTABLE_NAME}).".log";
	if (! open($G_LOG,">".$h_ref_param->{LOG}))
	{
	    warning "Still cannot create alternative log file ".$h_ref_param->{LOG}.". No log will be performed.\n";
	    $G_LOG=0;
	}
    }
    
    $h_ref_param->{RELEASE_DATE}="2007/06/226";
    
    # Following instruction forces flushing for each output to STDOUT or STDERR.
    $|=1;

    return 0;
  }

################################################################################
#
################################################################################
sub outtro
{
    my $h_ref_param=shift @_;
    if ($G_LOG)
    {
	close($G_LOG);
    }

    return 0;
}

################################################################################
#
################################################################################
sub main
{
  # This hash list will be used to store input parameters and some other
  # usefull information.
  # The actual valable keys are:
  #   VERSION:           string: current version of the tool.
  #   START_TIME:        string: start time of the script in the form YY_MM_DD.HH.MM.SS
  #   EXECUTABLE_NAME:   string: name of the current script.
  #   LOG:               string: name of the log file.
  #   RELEASE_DATE:      string: date of current tool release in form: YYYY/MM/DD
  #   DEBUG:             boolean: if this key exists, then the current script is run in
  #                               debug mode.
  #
  my %params=();
  
  if (intro(\%params)!=0)
  {
      error "Error while executing intro ... Aborting.\n";
      exit(1);
  }

  if (parse_args(\%params)!=0)
  {
      error "Aborting due to previous error(s). Use -h or --help for usage.\n";
      exit(1);
  }

  if (process(\%params)==0)
  {
      error "Error while processing ... Aborting.\n";
      exit(1);
  }

  if (outtro(\%params)!=0)
  {
      error "Error while executing outtro ... Aborting.\n";
      exit(1);
  }


}


################################################################################
#
################################################################################

main();
exit(0);

